﻿namespace WMS6.BLL
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using WMS6.Common;
    using WMS6.DataEntity;
    using WMS6.DBUtility;
    using WMS6.IDAL;
    using WMS6.QueryEntity;
    using WMS6.DALFactory;

    public class InvoiceBLL
    {
        private static readonly IBillingDailyInvDA billingDailyInvDA = DataAccess.CreateBillingDailyInvDA();
        private static readonly IBillingEntityDA billingEntityDA = DataAccess.CreateBillingEntityDA();
        private static readonly ICarrierDA carrierDA = DataAccess.CreateCarrierDA();
        private static readonly ICommonMethodDA commonMethod = DataAccess.CreateCommonMethod();
        private static readonly ICustomerDA customerDA = DataAccess.CreateCustomerDA();
        private List<string> dataBaseID;
        private static readonly IDbConfigDA dbConfigDA = DataAccess.CreateDbConfigDA();
        private static readonly IInvoiceDA InvoiceDA = DataAccess.CreateInvoiceDA();
        private static readonly IInvoiceDetailDA invoiceDetailDA = DataAccess.CreateInvoiceDetailDA();
        private static readonly IInvoicePaymentDetailDA invoicePaymentDetailDA = DataAccess.CreateInvoicePaymentDetailDA();
        private PubParasInfo pubParasInfo;
        private static readonly IStatementDA statementDA = DataAccess.CreateStatementDA();
        private static readonly IStatementDetailDA statementDetailDA = DataAccess.CreateStatementDetailDA();
        private static readonly ITradePartnerDA tradePartnerDA = DataAccess.CreateTradePartnerDA();
        private static readonly IVendorDA vendorDA = DataAccess.CreateVendorDA();

        public InvoiceBLL()
        {
            this.pubParasInfo = null;
        }

        public InvoiceBLL(string currentWH)
        {
            this.pubParasInfo = null;
            if (!string.IsNullOrEmpty(currentWH))
            {
                this.dataBaseID = commonMethod.GetDataBaseID(currentWH);
                if (this.dataBaseID == null)
                {
                    PublicMethod.GetInstance().ShowAlertMessage("C001");
                }
            }
            else
            {
                PublicMethod.GetInstance().ShowAlertMessage("C002");
            }
        }

        public InvoiceBLL(PubParasInfo tempPubParasInfo)
        {
            this.pubParasInfo = null;
            if (!string.IsNullOrEmpty(tempPubParasInfo.CurrentWH))
            {
                this.dataBaseID = commonMethod.GetDataBaseID(tempPubParasInfo.CurrentWH);
                if (this.dataBaseID == null)
                {
                    PublicMethod.GetInstance().ShowAlertMessage("C001", this.pubParasInfo.UserLanguage);
                }
                else
                {
                    this.pubParasInfo = new PubParasInfo();
                    this.pubParasInfo = tempPubParasInfo;
                }
            }
            else
            {
                PublicMethod.GetInstance().ShowAlertMessage("C002", this.pubParasInfo.UserLanguage);
            }
        }

        public string DeleteInvoice(InvoiceInfo obj)
        {
            string whLoginID = this.dataBaseID[0];
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            string temp = string.Empty;
            try
            {
                List<InvoiceDetailInfo> invoiceDetailListInfo = invoiceDetailDA.GetInvoiceDetailListByID(dataBase, tran, obj.InvoiceID, whLoginID, this.pubParasInfo);
                if ((invoiceDetailListInfo != null) && (invoiceDetailListInfo.Count > 0))
                {
                    for (int i = 0; i < invoiceDetailListInfo.Count; i++)
                    {
                        if (invoiceDetailListInfo[i].Status != "New")
                        {
                            PublicMethod.GetInstance().ShowAlertMessage("F9200_007", this.pubParasInfo.UserLanguage);
                        }
                        StatementInfo statementInfo = statementDA.GetStatementByID(dataBase, tran, invoiceDetailListInfo[i].StatementID, this.dataBaseID[0]);
                        if (statementInfo != null)
                        {
                            statementInfo.InvoiceAmount -= invoiceDetailListInfo[i].InvoiceAmount;
                            statementInfo.UpdatedBy = this.pubParasInfo.UserID;
                            if (statementInfo.InvoiceAmount > 0M)
                            {
                                statementInfo.Status = "Processing";
                            }
                            else
                            {
                                statementInfo.Status = "Reviewed";
                            }
                            statementDA.UpdateStatement(dataBase, tran, statementInfo, this.dataBaseID[0]);
                        }
                    }
                }
                List<string> gInitLocal3 = new List<string> {
                    obj.InvoiceID
                };
                invoiceDetailDA.DeleteInvoiceDetail(gInitLocal3, this.dataBaseID);
                if (InvoiceDA.DeleteInvoice(dataBase, tran, new List<string> { obj.InvoiceID }, this.dataBaseID) > 0)
                {
                    temp = obj.InvoiceID;
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }

        public string DeleteInvoiceDetail(List<string> invoiceID, List<string> lineID)
        {
            string statementID = string.Empty;
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            string temp = string.Empty;
            try
            {
                int i;
                for (i = 0; i < invoiceID.Count; i++)
                {
                    InvoiceDetailInfo invoiceDetail = invoiceDetailDA.GetInvoiceDetailByID(dataBase, tran, invoiceID[i], lineID[i], this.dataBaseID[0], this.pubParasInfo);
                    if (invoiceDetail.Status != "New")
                    {
                        PublicMethod.GetInstance().ShowAlertMessage("F9200_007", this.pubParasInfo.UserLanguage);
                    }
                    statementID = invoiceDetail.StatementID;
                    StatementInfo statementInfo = statementDA.GetStatementByID(dataBase, tran, statementID, this.dataBaseID[0]);
                    if (statementInfo != null)
                    {
                        statementInfo.InvoiceAmount -= invoiceDetail.InvoiceAmount;
                        statementInfo.UpdatedBy = this.pubParasInfo.UserID;
                        if (statementInfo.InvoiceAmount > 0M)
                        {
                            statementInfo.Status = "Processing";
                        }
                        else
                        {
                            statementInfo.Status = "Reviewed";
                        }
                        statementDA.UpdateStatement(dataBase, tran, statementInfo, this.dataBaseID[0]);
                    }
                }
                int result = invoiceDetailDA.DeleteInvoiceDetail(dataBase, tran, invoiceID, lineID, this.dataBaseID);
                if (result > 0)
                {
                    for (i = 0; i < invoiceID.Count; i++)
                    {
                        bool isNew = true;
                        List<InvoiceDetailInfo> invoiceDetailListInfo = invoiceDetailDA.GetInvoiceDetailListByID(dataBase, tran, invoiceID[i], this.dataBaseID[0], this.pubParasInfo);
                        for (int j = 0; j < invoiceDetailListInfo.Count; j++)
                        {
                            if (invoiceDetailListInfo[i].Status != "New")
                            {
                                isNew = false;
                                break;
                            }
                        }
                        if (isNew)
                        {
                            InvoiceInfo invoiceInfo = InvoiceDA.GetInvoiceByID(dataBase, tran, invoiceID[i], this.dataBaseID[0]);
                            invoiceInfo.Status = "New";
                            invoiceInfo.UpdatedBy = this.pubParasInfo.UserID;
                            InvoiceDA.UpdateInvoice(dataBase, tran, invoiceInfo, this.dataBaseID);
                        }
                    }
                    temp = result.ToString();
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }

        public DataSet GetAllInvoiceInfo()
        {
            return InvoiceDA.GetAllInvoice(this.dataBaseID[0], this.pubParasInfo);
        }

        public InvoiceDetailInfo GetInvoiceDetailInfoByID(string invoiceID, string lineID)
        {
            return invoiceDetailDA.GetInvoiceDetailByID(invoiceID, lineID, this.dataBaseID[0], this.pubParasInfo);
        }

        public InvoiceInfo GetInvoiceInfoByID(string id)
        {
            InvoiceInfo invoiceInfo = InvoiceDA.GetInvoiceByID(id, this.dataBaseID[0]);
            if (invoiceInfo != null)
            {
                invoiceInfo.InvoiceDetailListInfo = invoiceDetailDA.GetInvoiceDetailListByID(id, this.dataBaseID[0], this.pubParasInfo);
                invoiceInfo.InvoicePaymentDetailListInfo = invoicePaymentDetailDA.GetInvoicePaymentDetailListByID(id, this.dataBaseID[0]);
            }
            return invoiceInfo;
        }

        public DataSet GetInvoiceInfoByQueryEntity(InvoiceQueryEntity invoiceQueryEntity)
        {
            List<string> sqlWhere = new List<string>();
            if (!string.IsNullOrEmpty(invoiceQueryEntity.InvoiceID))
            {
                sqlWhere.Add("INVOICE_ID " + invoiceQueryEntity.InvoiceID);
            }
            if (!string.IsNullOrEmpty(invoiceQueryEntity.BillingObject))
            {
                sqlWhere.Add(" BILLING_OBJECT " + invoiceQueryEntity.BillingObject);
            }
            if (!string.IsNullOrEmpty(invoiceQueryEntity.BillingObjectID))
            {
                sqlWhere.Add(" BILLING_OBJECT_ID " + invoiceQueryEntity.BillingObjectID);
            }
            if (!string.IsNullOrEmpty(invoiceQueryEntity.DueFromTo))
            {
                sqlWhere.Add(" DUE_FROM_TO " + invoiceQueryEntity.DueFromTo);
            }
            if (!string.IsNullOrEmpty(invoiceQueryEntity.Status))
            {
                sqlWhere.Add(" STATUS " + invoiceQueryEntity.Status);
            }
            return InvoiceDA.GetInvoiceByQueryList(sqlWhere, invoiceQueryEntity, this.dataBaseID[0], this.pubParasInfo);
        }

        public string InsertInvoice(InvoiceInfo obj)
        {
            bool billingObject = true;
            string whLoginID = this.dataBaseID[0];
            if (obj.BillingObject.ToUpper() == "Owner".ToUpper())
            {
                if (!tradePartnerDA.CheckTradePartnerIDUnique(obj.BillingObjectID, whLoginID))
                {
                    billingObject = false;
                }
            }
            else if (obj.BillingObject.ToUpper() == "Vendor".ToUpper())
            {
                if (!vendorDA.CheckVendorIDUnique(obj.BillingObjectID, whLoginID))
                {
                    billingObject = false;
                }
            }
            else if (obj.BillingObject.ToUpper() == "Customer".ToUpper())
            {
                if (!customerDA.CheckCustomerIDUnique(obj.BillingObjectID, whLoginID))
                {
                    billingObject = false;
                }
            }
            else if (obj.BillingObject.ToUpper() == "Carrier".ToUpper())
            {
                if (!carrierDA.CheckCarrierIDUnique(obj.BillingObjectID, whLoginID))
                {
                    billingObject = false;
                }
            }
            else if ((obj.BillingObject.ToUpper() == "BillingEntity".ToUpper()) && !billingEntityDA.CheckBillingEntityIDUnique(obj.BillingObjectID, whLoginID))
            {
                billingObject = false;
            }
            if (!billingObject)
            {
                PublicMethod.GetInstance().ShowAlertMessage("F9180_003", this.pubParasInfo.UserLanguage, new List<string> { obj.BillingObjectID });
            }
            if (InvoiceDA.CheckInvoiceIDUnique(obj.InvoiceID, whLoginID))
            {
                PublicMethod.GetInstance().ShowAlertMessage("F9200_005", this.pubParasInfo.UserLanguage, new List<string> { obj.InvoiceID });
            }
            return this.InsertInvoiceInfo(obj);
        }

        public string InsertInvoiceDetail(InvoiceDetailInfo invoiceDetailInfo)
        {
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            string temp = string.Empty;
            try
            {
                int result = 0;
                StatementInfo statementInfo = statementDA.GetStatementByID(dataBase, tran, invoiceDetailInfo.StatementID, this.dataBaseID[0]);
                if (invoiceDetailDA.GetInvoiceDetailByID(dataBase, tran, invoiceDetailInfo.InvoiceID, invoiceDetailInfo.LineID.ToString(), this.dataBaseID[0], this.pubParasInfo) == null)
                {
                    if (statementInfo != null)
                    {
                        statementInfo.InvoiceAmount += invoiceDetailInfo.InvoiceAmount;
                        statementInfo.UpdatedBy = this.pubParasInfo.UserID;
                        statementInfo.Status = "Processing";
                        statementDA.UpdateStatement(dataBase, tran, statementInfo, this.dataBaseID[0]);
                    }
                    result = invoiceDetailDA.InsertInvoiceDetail(dataBase, tran, invoiceDetailInfo, this.dataBaseID);
                }
                else
                {
                    InvoiceDetailInfo invoiceDetail = invoiceDetailDA.GetInvoiceDetailByID(dataBase, tran, invoiceDetailInfo.InvoiceID, invoiceDetailInfo.LineID.ToString(), this.dataBaseID[0], this.pubParasInfo);
                    if (statementInfo != null)
                    {
                        statementInfo.InvoiceAmount = (statementInfo.InvoiceAmount + invoiceDetailInfo.InvoiceAmount) - invoiceDetail.InvoiceAmount;
                        statementInfo.UpdatedBy = this.pubParasInfo.UserID;
                        statementDA.UpdateStatement(dataBase, tran, statementInfo, this.dataBaseID[0]);
                    }
                    result = invoiceDetailDA.UpdateInvoiceDetail(dataBase, tran, invoiceDetailInfo, this.dataBaseID);
                }
                if (result > 0)
                {
                    temp = invoiceDetailInfo.LineID.ToString();
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }

        private string InsertInvoiceInfo(InvoiceInfo obj)
        {
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            string temp = string.Empty;
            try
            {
                if (InvoiceDA.InsertInvoice(dataBase, tran, obj, this.dataBaseID) > 0)
                {
                    temp = obj.InvoiceID;
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }

        public string InsertInvoicePaymentDetail(List<InvoicePaymentDetailInfo> invoicePaymentDetailListInfo)
        {
            string temp = string.Empty;
            if ((invoicePaymentDetailListInfo != null) && (invoicePaymentDetailListInfo.Count > 0))
            {
                DataBase dataBase = new DataBase();
                DbConnection conn = dataBase.connection;
                conn.Open();
                DbTransaction tran = conn.BeginTransaction();
                try
                {
                    int result = 0;
                    string invoiceID = invoicePaymentDetailListInfo[0].InvoiceID;
                    int maxseq_no = int.Parse(invoicePaymentDetailDA.GetInvoicePaymentDetailMaxSeq(dataBase, tran, invoicePaymentDetailListInfo[0].InvoiceID, this.dataBaseID[0])) + 10;
                    for (int i = 0; i < invoicePaymentDetailListInfo.Count; i++)
                    {
                        InvoiceDetailInfo invoiceDetailInfo = invoiceDetailDA.GetInvoiceDetailByID(dataBase, tran, invoicePaymentDetailListInfo[i].InvoiceID, invoicePaymentDetailListInfo[i].LineID.ToString(), this.dataBaseID[0], this.pubParasInfo);
                        if (invoiceDetailInfo != null)
                        {
                            StatementInfo statementInfo = statementDA.GetStatementByID(dataBase, tran, invoiceDetailInfo.StatementID, this.dataBaseID[0]);
                            if (statementInfo != null)
                            {
                                statementInfo.PayAmount += invoicePaymentDetailListInfo[i].PayAmount;
                                statementInfo.UpdatedBy = this.pubParasInfo.UserID;
                                statementInfo.PaymentDate = DateTime.Now;
                                if (statementInfo.PayAmount >= statementInfo.TotalAmount)
                                {
                                    statementInfo.Status = "Closed";
                                }
                                else
                                {
                                    statementInfo.Status = "Processing";
                                }
                                statementDA.UpdateStatement(dataBase, tran, statementInfo, this.dataBaseID[0]);
                            }
                            decimal payment = invoiceDetailInfo.PayAmount + invoicePaymentDetailListInfo[i].PayAmount;
                            if (payment >= invoiceDetailInfo.InvoiceAmount)
                            {
                                invoiceDetailInfo.Status = "Closed";
                            }
                            else
                            {
                                invoiceDetailInfo.Status = "PartPayment";
                            }
                            invoiceDetailInfo.PayAmount = payment;
                            invoiceDetailInfo.UpdatedBy = this.pubParasInfo.UserID;
                            invoiceDetailDA.UpdateInvoiceDetail(invoiceDetailInfo, this.dataBaseID);
                        }
                        invoicePaymentDetailListInfo[i].SeqNo = maxseq_no;
                        maxseq_no += 10;
                        result += invoicePaymentDetailDA.InsertInvoicePaymentDetail(dataBase, tran, invoicePaymentDetailListInfo[i], this.dataBaseID);
                    }
                    if (result > 0)
                    {
                        bool isClosed = true;
                        List<InvoiceDetailInfo> invoiceDetailListInfo = invoiceDetailDA.GetInvoiceDetailListByID(dataBase, tran, invoiceID, this.dataBaseID[0], this.pubParasInfo);
                        for (int j = 0; j < invoiceDetailListInfo.Count; j++)
                        {
                            if (invoiceDetailListInfo[j].Status != "Closed")
                            {
                                isClosed = false;
                                break;
                            }
                        }
                        InvoiceInfo invoiceInfo = InvoiceDA.GetInvoiceByID(dataBase, tran, invoiceID, this.dataBaseID[0]);
                        if (isClosed)
                        {
                            invoiceInfo.Status = "Closed";
                        }
                        else
                        {
                            invoiceInfo.Status = "Processing";
                        }
                        invoiceInfo.UpdatedBy = this.pubParasInfo.UserID;
                        InvoiceDA.UpdateInvoice(dataBase, tran, invoiceInfo, this.dataBaseID);
                        temp = result.ToString();
                    }
                    tran.Commit();
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    CommonErrorHandler.ErrorHandler(ex, LogType.Error);
                }
                finally
                {
                    conn.Close();
                }
            }
            return temp;
        }

        public string UpdateInvoice(InvoiceInfo obj)
        {
            string whLoginID = this.dataBaseID[0];
            if (!InvoiceDA.CheckInvoiceIDUnique(obj.InvoiceID, whLoginID))
            {
                PublicMethod.GetInstance().ShowAlertMessage("F9200_004", this.pubParasInfo.UserLanguage, new List<string> { obj.InvoiceID });
            }
            return this.UpdateInvoiceInfo(obj);
        }

        private string UpdateInvoiceInfo(InvoiceInfo obj)
        {
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            string temp = string.Empty;
            try
            {
                if (InvoiceDA.UpdateInvoice(dataBase, tran, obj, this.dataBaseID) > 0)
                {
                    temp = obj.InvoiceID;
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }

        public string UpdateInvoiceSubmit(List<InvoiceInfo> obj)
        {
            string temp = string.Empty;
            string whLoginID = this.dataBaseID[0];
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            try
            {
                for (int i = 0; i < obj.Count; i++)
                {
                    if (!InvoiceDA.CheckInvoiceIDUnique(dataBase, tran, obj[i].InvoiceID, whLoginID))
                    {
                        PublicMethod.GetInstance().ShowAlertMessage("F9200_004", this.pubParasInfo.UserLanguage, new List<string> { obj[i].InvoiceID });
                    }
                    InvoiceInfo invoiceInfo = InvoiceDA.GetInvoiceByID(dataBase, tran, obj[i].InvoiceID, whLoginID);
                    invoiceInfo.IsAmountSubmit = obj[i].IsAmountSubmit;
                    invoiceInfo.IsInvoiceSubmit = obj[i].IsInvoiceSubmit;
                    invoiceInfo.UpdatedBy = this.pubParasInfo.UserID;
                    if (InvoiceDA.UpdateInvoice(dataBase, tran, invoiceInfo, this.dataBaseID) > 0)
                    {
                        temp = temp + obj[i].InvoiceID;
                    }
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return temp;
        }
    }
}

